package com.pan.admin.quartz.task;

import com.gitee.apanlh.spring.BeanContextUtils;
import com.gitee.apanlh.util.base.BigDecimalUtils;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Empty;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.reflection.CopyUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.pan.admin.module.api.dao.ApiKeyDao;
import com.pan.admin.module.api.entity.ApiKey;
import com.pan.admin.module.api.service.ApiKeyService;
import com.pan.admin.module.channel.dao.LoanChannelDao;
import com.pan.admin.module.channel.entity.LoanChannel;
import com.pan.admin.module.channel.service.LoanChannelService;
import com.pan.admin.module.loanProduct.dao.LoanProductDao;
import com.pan.admin.module.loanProduct.dao.LoanProductPlanDao;
import com.pan.admin.module.loanProduct.entity.LoanProduct;
import com.pan.admin.module.loanProduct.entity.LoanProductPlan;
import com.pan.admin.module.loanProduct.entity.vo.LoanProductPlanVO;
import com.pan.admin.module.loanProduct.service.LoanProductPlanService;
import com.pan.admin.module.loanProduct.service.LoanProductService;
import com.pan.admin.module.market.dao.LoanMarketDao;
import com.pan.admin.module.market.entity.LoanMarket;
import com.pan.admin.module.market.service.LoanMarketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

/**
 *  从生产环境拷贝到Test环境拷贝重要数据
 *
 *  @author Pan
 */
@Component
public class PreCopyProdApiTask {

    @Autowired
    private ApiKeyService apiKeyService;
    @Autowired
    private LoanChannelService loanChannelService;
    @Autowired
    private LoanProductService loanProductService;
    @Autowired
    private LoanProductPlanService loanProductPlanService;
    @Autowired
    private LoanMarketService loanMarketService;

    @Autowired
    private ApiKeyDao apiKeyDao;
    @Autowired
    private LoanChannelDao loanChannelDao;
    @Autowired
    private LoanProductDao loanProductDao;
    @Autowired
    private LoanProductPlanDao loanProductPlanDao;
    @Autowired
    private LoanMarketDao loanMarketDao;

    public PreCopyProdApiTask() {
        super();
    }

    @PostConstruct
    private void copy() {
        String activeProfile = BeanContextUtils.getApplicationContext().getEnvironment().getActiveProfiles()[0];
        if (!Eq.str("test-in", activeProfile)) {
            return ;
        }

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
            List<ApiKey> listInsertApi = syncApiKey();
            List<LoanChannel> listInsertChannel = syncLoanChannel();
            apiKeyCorrectionLoanChannelId(listInsertApi, listInsertChannel);

            syncProduct();
            syncProductPlan();

            syncMarket();
            }
        }, 0, 60000l);
    }

    private List<ApiKey> syncApiKey() {
        List<ApiKey> listApi = apiKeyService.list(null);
        List<ApiKey> listProdApi = apiKeyService.listSlave(null);

        List<String> listApiClientId = CollUtils.toList(listApi, t -> t.getApiClientId());
        List<String> prodApiClientId = CollUtils.toList(listProdApi, t -> t.getApiClientId());

        Set<String> difference = CollUtils.difference(prodApiClientId, listApiClientId);
        if (ValidParam.isEmpty(difference)) {
            return Empty.list();
        }

        List<ApiKey> listInsertApi = CollUtils.newArrayList();
        IteratorUtils.collection(difference, (t, i) -> {
            ApiKey one = CollUtils.findOne(listProdApi, find -> Eq.str(find.getApiClientId(), t));
            apiKeyDao.insertApiKeys(one);
            listInsertApi.add(one);
        });
        return listInsertApi;

    }

    private List<LoanChannel> syncLoanChannel() {
        List<LoanChannel> listChannel = loanChannelService.list(null);
        List<LoanChannel> listProdChannel = loanChannelService.listSlave(null);

        List<String> listCode = CollUtils.toList(listChannel, t -> t.getUniqueCode());
        List<String> prodCode = CollUtils.toList(listProdChannel, t -> t.getUniqueCode());

        Set<String> differenceChannel = CollUtils.difference(prodCode, listCode);
        if (ValidParam.isEmpty(differenceChannel)) {
            return Empty.list();
        }

        List<LoanChannel> listInsertChannel = CollUtils.newArrayList();
        IteratorUtils.collection(differenceChannel, (t, i) -> {
            LoanChannel loanChannel = CollUtils.findOne(listProdChannel, find -> Eq.str(find.getUniqueCode(), t));
            listInsertChannel.add(loanChannel);
            loanChannelDao.insertLoanChannel(loanChannel);
        });
        return listInsertChannel;
    }

    /**
     *  修正API-loan_channel外键
     *
     *  @param listInsertApi
     *  @param listInsertChannel
     */
    private void apiKeyCorrectionLoanChannelId(List<ApiKey> listInsertApi, List<LoanChannel> listInsertChannel) {
        if (ValidParam.isEmpty(listInsertApi)) {
            return ;
        }

        List<LoanChannel> listLoanChannel = CollUtils.find(listInsertChannel, t -> t.getType().equals(3));
        IteratorUtils.array(listLoanChannel, loanChannel -> {
            String uniqueCode = loanChannel.getUniqueCode();

            //  修正id
            ApiKey updateApikey = CollUtils.findOne(listInsertApi, insertApiKey -> insertApiKey.getApiClientId().equals(uniqueCode));
            if (ValidParam.isNotNull(updateApikey)) {
                updateApikey.setLoanChannelId(loanChannel.getId());
                updateApikey.setBalance(null);
                apiKeyDao.updateApiKeys(updateApikey);
            }
        });
    }

    private void syncProduct() {
        List<LoanProduct> listProduct = loanProductService.list(null);
        List<LoanProduct> listProdProduct = loanProductService.listSlave(null);

        List<Long> listId = CollUtils.toList(listProduct, t -> t.getId());
        List<Long> listProdId = CollUtils.toList(listProdProduct, t -> t.getId());

        Set<Long> difference = CollUtils.difference(listProdId, listId);
        if (ValidParam.isEmpty(difference)) {
            return ;
        }

        IteratorUtils.collection(difference, (prodId, i) -> {
            LoanProduct loanProduct = CollUtils.findOne(listProdProduct, find -> Eq.object(find.getId(), prodId));
            //  修改临时余额
            loanProduct.setBalance(BigDecimalUtils.toBigDecimal(2000));
            loanProductDao.insertLoanProduct(loanProduct);
        });
    }

    private void syncProductPlan() {
        List<LoanProductPlan> listProduct = loanProductPlanService.listAll();
        List<LoanProductPlan> listProdProduct = loanProductPlanService.listAllSlave();

        List<Long> listId = CollUtils.toList(listProduct, t -> t.getId());
        List<Long> listProdId = CollUtils.toList(listProdProduct, t -> t.getId());

        Set<Long> difference = CollUtils.difference(listProdId, listId);
        if (ValidParam.isEmpty(difference)) {
            return ;
        }

        IteratorUtils.collection(difference, (prodId, i) -> {
            LoanProductPlan loanProductPlan = CollUtils.findOne(listProdProduct, find -> Eq.object(find.getId(), prodId));
            //  默认禁用
            loanProductPlan.setStatus(0L);
            //  默认所有检测关闭
            loanProductPlan.setEnableApplyEmptyCheck(0);
            loanProductPlan.setEnableFilterMd5(0);
            loanProductPlan.setEnableFilterLocal(0);
            loanProductPlan.setEnableApplyTwoElement(0);
            loanProductPlan.setEnableApplyThreeElement(0);
            loanProductPlan.setEnableMultiPush(0);
            LoanProductPlanVO copy = CopyUtils.copy(loanProductPlan, LoanProductPlanVO.class);
            loanProductPlanDao.insertLoanProductPlan(copy);
        });
    }

    private void syncMarket() {
        List<LoanMarket> list = loanMarketService.list(null);
        List<LoanMarket> listProd = loanMarketService.listSlave(null);

        List<Long> listId = CollUtils.toList(list, t -> t.getId());
        List<Long> listProdId = CollUtils.toList(listProd, t -> t.getId());

        Set<Long> difference = CollUtils.difference(listProdId, listId);
        if (ValidParam.isEmpty(difference)) {
            return ;
        }

        IteratorUtils.collection(difference, (prodId, i) -> {
            LoanMarket loanMarket = CollUtils.findOne(listProd, find -> Eq.object(find.getId(), prodId));
            loanMarketDao.insertLoanMarket(loanMarket);
        });

    }
}
